﻿using System;
using System.Collections.Generic;
using System.Text;

using LuaInterface;
using KopiLua;

namespace SimpleTest
{
    public class Foo
    {
        public double m = 3;

        public double multiply(double x)
        {
            return x * m;
        }

        public static bool OutMethod(Foo foo, out Bar bar)
        {
            bar = new Bar() { x = foo.m };
            return true;
        }
    };

    public class Bar
    {
        public double x;
    };
	    
	class Program
	{
        static void Main(string[] args)
        {
            Lua.lua_State luaState = LuaI.init();
            
            LuaI.set(luaState, "x", 3);
            LuaI.DoString(luaState, "y=x");
            Console.WriteLine("y={0}", LuaI.get(luaState, "y"));

            {
                LuaI.DoString(luaState, "luanet.load_assembly('SimpleTest')");
                LuaI.DoString(luaState, "Foo = luanet.import_type('SimpleTest.Foo')");
                LuaI.DoString(luaState, "method = luanet.get_method_bysig(Foo, 'OutMethod', 'SimpleTest.Foo', 'out SimpleTest.Bar')");
                Console.WriteLine(LuaI.get(luaState, "method"));
            }

            {
                object[] retVals = LuaI.DoString(luaState, "return 1,'hello'");
                Console.WriteLine("{0},{1}", retVals[0], retVals[1]);
            }

            {
                KopiLua.Lua.lua_pushcfunction(luaState, Func);
                KopiLua.Lua.lua_setglobal(luaState, "func");
                Console.WriteLine("registered 'func'");

                double result = (double)LuaI.DoString(luaState, "return func(1,2,3)")[0];
                Console.WriteLine("{0}", result);
            }

            {
                Bar bar = new Bar();
                bar.x = 2;
                LuaI.set(luaState, "bar", bar);
                Console.WriteLine("'bar' registered");

                object o = LuaI.get(luaState, "bar");
                Console.WriteLine("'bar' read back as {0}", o);
                Console.WriteLine(o == bar ? "same" : "different");
                Console.WriteLine("LuaInterface says bar.x = {0}", LuaI.get(luaState, "bar.x"));

                double result = (double)LuaI.DoString(luaState, "return bar.x")[0];
                Console.WriteLine("lua says bar.x = {0}", result);

                LuaI.DoString(luaState, "bar.x = 4");
                Console.WriteLine("now bar.x = {0}", bar.x);
            }

            {
                Foo foo = new Foo();
                LuaI.RegisterFunction(luaState, "multiply", foo, foo.GetType().GetMethod("multiply"));
                Console.WriteLine("registered 'multiply'");

                double result = (double)LuaI.DoString(luaState, "return multiply(3)")[0];
                Console.WriteLine("{0}", result);
            }

            Console.WriteLine("Finished, press Enter to quit");
            Console.ReadLine();
        }

        static int Func(KopiLua.Lua.lua_State L)
        {
            int n = KopiLua.Lua.lua_gettop(L);
            KopiLua.Lua.lua_pushnumber(L, n * 2);
            return 1;
        }

	}
}